package org.github.config;

import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
import cn.dev33.satoken.stp.StpUtil;
import com.google.common.collect.ImmutableList;
import java.util.Map;
import javax.annotation.Resource;
import lombok.val;
import org.github.core.props.DynamicProps;
import org.github.core.spring.mvc.ReturnableValueHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import static cn.dev33.satoken.jwt.SaJwtUtil.createToken;
import static cn.dev33.satoken.router.SaRouter.notMatch;
import static com.google.common.base.MoreObjects.firstNonNull;
import static org.github.core.Const.LOGIN_TYPE_NAME;

@Configuration
public class WebMvcConfigWithSaToken implements WebMvcConfigurer {
  @Resource
  private DynamicProps dynamicProps;

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry
      .addInterceptor(new SaInterceptor(ignore -> notMatch(dynamicProps.getWhiteList()).check(StpUtil::checkLogin)))
      .addPathPatterns("/**");
  }

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
  }

  @Bean
  public ReturnableValueHandler returnableValueHandler(RequestMappingHandlerAdapter adapter) {
    val handler = ReturnableValueHandler.INSTANCE;
    val origin  = firstNonNull(adapter.getReturnValueHandlers(), ImmutableList.<HandlerMethodReturnValueHandler>of());
    val target  = ImmutableList.<HandlerMethodReturnValueHandler>builder().add(handler).addAll(origin).build();
    adapter.setReturnValueHandlers(target);
    return handler;
  }

  @Bean
  public StpLogicJwtForSimple stpLogicJwt() {
    return new StpLogicJwtForSimple(LOGIN_TYPE_NAME) {
      @Override
      public String createTokenValue(Object loginId, String device, long timeout, Map<String,Object> extraData) {
        return createToken(loginType, loginId, device, timeout, extraData, jwtSecretKey());
      }
    };
  }
}
